﻿define(function (require, exports, moudles) {
    return function (jquery) {
        (function ($) {
            $.fn.collapsible = function (options) {
                var defaults = {
                    accordion: undefined
                };
                options = $.extend(defaults, options);

                return this.each(function () {
                    var $this = $(this);
                    var $panel_headers = $(this).find('> li > .collapsible-header');
                    var collapsible_type = $this.data("collapsible");
                    // Turn off any existing event handlers
                    $this.off('click.collapse', '.collapsible-header');
                    $panel_headers.off('click.collapse');

                    /****************
                    Helper Functions
                    ****************/
                    // Accordion Open
                    function accordionOpen(object) {
                        $panel_headers = $this.find('> li > .collapsible-header');
                        if (object.hasClass('active')) {
                            object.parent().addClass('active');
                        }
                        else {
                            object.parent().removeClass('active');
                        }
                        if (object.parent().hasClass('active')) {
                            object.siblings('.collapsible-body').stop(true, false).slideDown({ duration: 350, easing: "easeOutQuart", queue: false, complete: function () { $(this).css('height', ''); } });
                        }
                        else {
                            object.siblings('.collapsible-body').stop(true, false).slideUp({ duration: 350, easing: "easeOutQuart", queue: false, complete: function () { $(this).css('height', ''); } });
                        }

                        $panel_headers.not(object).removeClass('active').parent().removeClass('active');
                        $panel_headers.not(object).parent().children('.collapsible-body').stop(true, false).slideUp(
                          {
                              duration: 350,
                              easing: "easeOutQuart",
                              queue: false,
                              complete:
                                function () {
                                    $(this).css('height', '');
                                }
                          });
                    }

                    // Expandable Open
                    function expandableOpen(object) {
                        if (object.hasClass('active')) {
                            object.parent().addClass('active');
                        }
                        else {
                            object.parent().removeClass('active');
                        }
                        if (object.parent().hasClass('active')) {
                            object.siblings('.collapsible-body').stop(true, false).slideDown({ duration: 350, easing: "easeOutQuart", queue: false, complete: function () { $(this).css('height', ''); } });
                        }
                        else {
                            object.siblings('.collapsible-body').stop(true, false).slideUp({ duration: 350, easing: "easeOutQuart", queue: false, complete: function () { $(this).css('height', ''); } });
                        }
                    }

                    /**
                     * Check if object is children of panel header
                     * @param  {Object}  object Jquery object
                     * @return {Boolean} true if it is children
                     */
                    function isChildrenOfPanelHeader(object) {

                        var panelHeader = getPanelHeader(object);

                        return panelHeader.length > 0;
                    }

                    /**
                     * Get panel header from a children element
                     * @param  {Object} object Jquery object
                     * @return {Object} panel header object
                     */
                    function getPanelHeader(object) {

                        return object.closest('li > .collapsible-header');
                    }

                    /*****  End Helper Functions  *****/

                    // Add click handler to only direct collapsible header children
                    $this.on('click.collapse', '> li > .collapsible-header', function (e) {
                        var $header = $(this),
                            element = $(e.target);

                        if (isChildrenOfPanelHeader(element)) {
                            element = getPanelHeader(element);
                        }

                        element.toggleClass('active');

                        if (options.accordion || collapsible_type === "accordion" || collapsible_type === undefined) { // Handle Accordion
                            accordionOpen(element);
                        } else { // Handle Expandables
                            expandableOpen(element);

                            if ($header.hasClass('active')) {
                                expandableOpen($header);
                            }
                        }
                    });

                    // Open first active
                    var $panel_headers = $this.find('> li > .collapsible-header');
                    if (options.accordion || collapsible_type === "accordion" || collapsible_type === undefined) { // Handle Accordion
                        accordionOpen($panel_headers.filter('.active').first());
                    }
                    else { // Handle Expandables
                        $panel_headers.filter('.active').each(function () {
                            expandableOpen($(this));
                        });
                    }

                });
            };
        })(jquery);
    }
})